#ifndef KEEP_ALIVE_H
#define KEEP_ALIVE_H




class keep_alive
{
public:
	static unsigned int process_packet(unsigned char *packet_buffer, 
		unsigned int max_length, unsigned int packet_length)
	{
		unsigned char *out_buffer = NULL;
		unsigned int sendlen = real_process_packet(packet_buffer, packet_length, &out_buffer);
		if (sendlen)
		{
			memcpy(packet_buffer, out_buffer, sendlen > max_length ? max_length : sendlen);			
		}
		return sendlen;
	}
	static unsigned int process_packet(boost::asio::streambuf &streambuf)
	{
		const unsigned char *packet_buffer = boost::asio::buffer_cast<const unsigned char*>(streambuf.data());
		unsigned int packet_length = streambuf.size();
		unsigned char *out_buffer = NULL;

		int sendlen = real_process_packet(packet_buffer, packet_length, &out_buffer);

		streambuf.consume(packet_length);
		if (sendlen)
		{
			unsigned char* out = boost::asio::buffer_cast<unsigned char*>(streambuf.prepare(sendlen));
			memcpy(out, out_buffer, sendlen);	
			streambuf.commit(sendlen);
		}
		return sendlen;
	}
	static unsigned int real_process_packet(const unsigned char *packet_buffer, 
		unsigned int packet_length, unsigned char **out_buffer)
	{
		struct udp_packet_keepalive_client * client;

		int id;
		char type;

		/* check packet length */
		if (packet_length < sizeof(struct udp_packet_keepalive_client) + MD5_LENGTH)
		{
			cout << "Bad packet length : " << packet_length << ". Discard it." << endl;
			return 0;
		}
		client = (struct udp_packet_keepalive_client *)packet_buffer;
		id = client->table_id;
		type = client->type;
		/* check packet type */
		if ((type != CLIENT_EXIT) && (type != CLIENT_KEEPALIVE) && (type != CLIENT_QUERY))
		{
			cout << "[udp packet]Error packet id" << endl;
			return 0;
		}

		/* check table id */
		if (!user_info::valid_accounting_id(id)) 
		{
			cout << "[udp packet]Error packet table id " << id << endl;
			return 0;
		}
		user_info_ptr user = user_info::get_user_info(id);
		if (!user.get())
		{
			cout << "[udp packet]Error find user " << endl;
			return 0;
		}

		return user->keep_alive_process(packet_buffer, packet_length, out_buffer);
	}

};



















#endif